package com.xux.dao;

import cn.hutool.core.collection.CollectionUtil;
import com.xux.dao.support.impl.AbstractDaoSupport;
import com.xux.model.bo.OrderSlicGroupBO;
import com.xux.model.po.OrderSlic;
import com.xux.service.impl.LookupLetPipelinesOperation;
import org.bson.Document;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Repository;
import java.util.Arrays;
import java.util.List;
import java.util.Map;


/**
 * @author: xux
 * @date: 2022-06-30 15:29
 * @version: 1.0
 **/
@Repository
public class OrderSlicDao extends AbstractDaoSupport<OrderSlic> {

    public List<OrderSlicGroupBO> testGroup(String outerId) {
        Criteria criteria = Criteria.where("outerId").is(outerId);
        List<OrderSlicGroupBO> list = group(criteria, "price", "tPrice", null, OrderSlicGroupBO.class, "shopId", "outerId");
        return list;
    }

    public List<Document> testGroupDocument(String outerId) {
        List<Criteria> criterias = CollectionUtil.newArrayList();
        Criteria criteria = Criteria.where("outerId").is(outerId);
        criterias.add(criteria);

        Criteria all = new Criteria();
        all.andOperator(criterias);
        //可以基于这种方式，创建一个注解，指定查询的字段，字段查询的类型（等于、大于、小于等），再创建一个公共查询类，所有入参类继承该类，通过调用该类的公共方法生成最终的Criteria
        //这样在对应的入参类中使用该注解，就能自动生成入参转换后Criteria了，不用每次都写入参转换逻辑了。
        List<Document> list = group(all, "price", "tPrice", null, Document.class, "shopId", "outerId");
        return list;
    }

    public List<Map> correlationQuery() {
        Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.lookup("teacherJob", "_id", "teacherId", "teacherJob"),
                //unwind：一行变多行
                Aggregation.unwind("teacherJob"),
                Aggregation.project("name", "teacherJob.jobName")
        );
        AggregationResults<Map> results = mongoTemplate.aggregate(aggregation, "teacher", Map.class);
        List<Map> customerOrdersList = results.getMappedResults();
        return customerOrdersList;
    }

    public List<Map> queryByParams(Long teacherId,String jName) {
        Aggregation aggregation = Aggregation.newAggregation(
                //匹配条件
                Aggregation.match(Criteria.where("_id").is(teacherId)),
                //左连接关联子集teacherJob
                Aggregation.lookup("teacherJob", "_id", "teacherId", "teacherJob"),
                //unwind：一行变多行
                Aggregation.unwind("teacherJob"),
                //需要查询的字段
                Aggregation.project("name","teacherJob.jobName")
                        //字段重命名
                        .and("teacherJob.jobName").as("jName")
                        //排序_id字段
                        .andExclude("_id"),
                //嵌套/再次匹配
                Aggregation.match(Criteria.where("jName").is(jName))
        );
        //调用查询
        AggregationResults<Map> results = mongoTemplate.aggregate(aggregation, "teacher", Map.class);
        //取出结果集
        List<Map> customerOrdersList = results.getMappedResults();
        //返回结果集
        return customerOrdersList;
    }

    public List<Map> groupAndCorrelation() {
        Document oneDoc = new Document("shopId", "$_id");
        oneDoc.put("slicDate", "$maxSlicDate");
        LookupLetPipelinesOperation lookupLetPipelinesOperation = LookupLetPipelinesOperation.lookup("orderSlic",
                oneDoc, new Document("$match",
                        new Document("$expr",
                                new Document("$and", Arrays.asList(new Document("$eq", Arrays.asList("$$shopId", "$shopId")), new Document("$eq", Arrays.asList("$$slicDate", "$slicDate"))))
                        )), "sub");

        Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.group("shopId").max("slicDate").as("maxSlicDate"),
                lookupLetPipelinesOperation
        );
        AggregationResults<Map> results = mongoTemplate.aggregate(aggregation, "orderSlic", Map.class);
        //System.out.println(results.getMappedResults());
        return results.getMappedResults();
    }
}
